home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / Apple Game Sprockets / NetSprocket 1.0.3 / NetSprocketTest Sources / NSTestApp.cp < prev    next >
Encoding:
Text File  |  1996-12-12  |  27.9 KB  |  1,180 lines  |  [TEXT/CWIE]

  1. /******************************************************************************
  2.  **                                                                              **
  3.  **     Module:        NSTestApp.cp                                             **                        
  4.  **                                                                              **
  5.  **                                                                              **
  6.  **     Purpose:     Test harness for NetSprocket                             **            
  7.  **                                                                              **
  8.  **     Copyright (C) 1996 Apple Computer, Inc.  All rights reserved.         **
  9.  **                                                                              **
  10.  **                                                                              **
  11.  *****************************************************************************/
  12.  
  13. #define VERBOSE 0
  14.  
  15. #include "NSTestApp.h"
  16. #include "CPlayerWindow.h"
  17. #include <LGrowZone.h>
  18. #include <LWindow.h>
  19. #include <PP_Messages.h>
  20. #include <PP_Resources.h>
  21. #include <PP_KeyCodes.h>
  22. #include <PPobClasses.h>
  23. #include <UDrawingState.h>
  24. #include <UMemoryMgr.h>
  25. #include <URegistrar.h>
  26. #include <LEditField.h>
  27. #include <iostream>
  28. #include <sioux.h>
  29. #include <stdio.h>
  30. #include <UModalDialogs.h>
  31. #include <LArrayIterator.h>
  32. #include <LString.h>
  33. #include <Fonts.h>
  34. #include <Strings.h>
  35. #include <OpenTptAppleTalk.h>
  36.  
  37. #include <NetSprocket.h>
  38.  
  39. // put declarations for resource ids (ResIDTs) here
  40.  
  41. const CommandT    cmd_Host                = 2000;
  42. const CommandT    cmd_Join                = 2001;
  43. const CommandT    cmd_Unadvertise            = 2002;
  44. const CommandT    cmd_Start                = 2003;
  45. const CommandT    cmd_Stop                = 2007;
  46. const CommandT    cmd_TestGroups            = 2004;
  47. const CommandT    cmd_GetPlayers            = 2005;
  48. const CommandT    cmd_GetGroups            = 2006;
  49. const CommandT    cmd_GetInfo                = 2050;
  50.  
  51. enum {kKeyboardState = 600, kGameStart, kGameEnd, kTestGroups, kPropogateOptions, kResyncMessage};
  52. Boolean IsPressed(unsigned short k);
  53. pascal Boolean MyJoinRequestHandler(NSpGameReference inGame, 
  54.                             NSpJoinRequestMessage *inMessage, void* inContext,
  55.                             Str255 outReason);
  56.  
  57. const char *kJoinRequestString = "Sprockets";
  58. //const StringPtr kNBPNameString = "\pNetSprocketTest11";
  59. const StringPtr kNBPNameString = "\pNSpT";
  60.  
  61. const UInt32    gPadCode = 0xDEADBEEF;
  62. UInt32    *oneKMessage;
  63. UInt32     *tenKMessage;
  64.  
  65. Boolean gGameOver;
  66. SInt32    gCountdown;
  67. NSpFlags    flags;
  68.  
  69. UInt32    gMessagePriority = 1;
  70. UInt32    gSendRate = 1;
  71. UInt32 gSendSize = 1;
  72. Boolean    gBlocking = false;
  73. Boolean gCallWNE = true;
  74.  
  75. Boolean gServerOnly;
  76.  
  77. UnsignedWide    startTime;
  78. UnsignedWide    baseTime;
  79. // ===========================================================================
  80. //        • Main Program
  81. // ===========================================================================
  82.  
  83. pascal Boolean MyJoinRequestHandler(NSpGameReference inGame, 
  84.                             NSpJoinRequestMessage *inMessage, void* inContext,
  85.                             Str255 outReason)
  86. {
  87.     LString::CopyPStr("\pYou forgot to say 'Simon says.'", outReason);
  88.     
  89.     return BlocksAreEqual(inMessage->customData, kJoinRequestString,
  90.                         inMessage->customDataLen);
  91. }
  92.  
  93. void main(void)
  94. {
  95.     SIOUXSettings.autocloseonquit = true;
  96.     SIOUXSettings.asktosaveonclose = true;
  97.     SIOUXSettings.initializeTB = false;
  98.     SIOUXSettings.setupmenus = false;
  99.     SIOUXSettings.standalone = false;
  100.                                     // Set Debugging options
  101.     SetDebugThrow_(debugAction_SourceDebugger);
  102.     SetDebugSignal_(debugAction_SourceDebugger);
  103.     InitializeHeap(3);                // Initialize Memory Manager
  104.                                     // Parameter is number of Master Pointer
  105.                                     //   blocks to allocate
  106.     
  107.                                     // Initialize standard Toolbox managers
  108.     UQDGlobals::InitializeToolbox(&qd);
  109.     gGameOver = false;        
  110.     gCountdown = 100;
  111.     flags = kNSpSendFlag_Normal | kNSpSendFlag_SelfSend;
  112.     new LGrowZone(20000);            // Install a GrowZone function to catch
  113.                                     //    low memory situations.
  114.     NSTestApp    theApp;            // replace this with your App type
  115.     
  116.     oneKMessage = (UInt32 *)NewPtr(1024);
  117.     tenKMessage = (UInt32 *)NewPtr((10 * 1024));
  118.     
  119.     for (int i = 12; i < 256; i++)
  120.     {
  121.         oneKMessage[i] = gPadCode;
  122.     }
  123.     for (int i = 12; i < 2560; i++)
  124.     {
  125.         tenKMessage[i] = gPadCode;
  126.     }
  127.     theApp.Run();
  128. }
  129.  
  130.  
  131. // ---------------------------------------------------------------------------
  132. //        • CPPStarterApp             // replace this with your App type
  133. // ---------------------------------------------------------------------------
  134. //    Constructor
  135.  
  136. NSTestApp::NSTestApp()
  137. {
  138.     // Register functions to create core PowerPlant classes
  139.     bHost = false;
  140.     bAdvertising = false;
  141.     bRunning = false;
  142.     theGame = NULL;
  143.     RegisterAllPPClasses();
  144.     URegistrar::RegisterClass(CPlayerWindow::class_ID, (ClassCreatorFunc) CPlayerWindow::CreatePlayerWindowStream);
  145.     gPulseBit = 0;
  146.     
  147. //    Initialize our player list
  148.     CPlayerListComparator *theComparator = new CPlayerListComparator();
  149.     ThrowIfNULL_(theComparator);
  150.     mPlayerList = new LArray(sizeof(PlayerListItem), theComparator, true);
  151.     ThrowIfNULL_(mPlayerList);
  152.  
  153. }
  154.  
  155.  
  156. // ---------------------------------------------------------------------------
  157. //        • ~NSTestApp            // replace this with your App type
  158. // ---------------------------------------------------------------------------
  159. //    Destructor
  160. //
  161.  
  162. NSTestApp::~NSTestApp()
  163. {
  164. }
  165.  
  166. // ---------------------------------------------------------------------------
  167. //        • StartUp
  168. // ---------------------------------------------------------------------------
  169. //    This function lets you do something when the application starts up. 
  170. //    For example, you could issue your own new command, or respond to a system
  171. //  oDoc (open document) event.
  172.  
  173. void
  174. NSTestApp::StartUp()
  175. {
  176.     OSStatus err;
  177.     UInt32    choice = 0;
  178.     NumVersion    vers;
  179.         
  180.     ObeyCommand(cmd_New, nil);        // EXAMPLE, create a new window
  181.     
  182. //    Do some quick and dirty testing
  183.     cout << "Starting up" << endl;
  184.     err =  NSpInitialize(500, 50000, 25, 'NSpT', 5000);
  185.     cout << "NSpInitialize: " << err << endl;
  186.     err = NSpInstallJoinRequestHandler(&MyJoinRequestHandler, NULL);
  187.     cout << "NSpInstallJoinRequestHandler returned " << err << endl;
  188.     vers = NSpGetVersion();
  189.     cout << "NetSprocket version is " << *((UInt32 *) &vers) << endl;
  190. }
  191.  
  192.  
  193. Boolean IsPressed(unsigned short k)
  194. // k =  any keyboard scan code, 0-127
  195. {
  196.     KeyMap map;
  197.     unsigned char km[16];
  198.     
  199.     GetKeys(map);
  200.     BlockMove(map, km, 16);
  201.  
  202.     Boolean pressed;
  203.     pressed = ( ( km[k>>3] >> (k & 7) ) & 1);
  204.     
  205.     return pressed;
  206. }
  207. int gLastTickCount = 0;
  208.  
  209. void
  210. NSTestApp::ProcessNextEvent()
  211. {
  212.     EventRecord        macEvent;
  213.     NSpMessageHeader        *theMessage;
  214.     OSStatus    status;
  215.     
  216.     if (gCallWNE)
  217.     {
  218.         if (IsOnDuty()) {
  219.                 
  220.                 // Calling OSEventAvail with a zero event mask will always
  221.                 // pass back a null event. However, it fills the EventRecord
  222.                 // with the information we need to set the cursor shape--
  223.                 // the mouse location in global coordinates and the state
  224.                 // of the modifier keys.
  225.                 
  226.             ::OSEventAvail(0, &macEvent);
  227.             AdjustCursor(macEvent);
  228.         }
  229.         
  230.             // Retrieve the next event. Context switch could happen here.
  231.         
  232.         Boolean    gotEvent = ::WaitNextEvent(everyEvent, &macEvent, 0,
  233.                                             mMouseRgnH);
  234.  
  235.  
  236.         Boolean SIOUXDidEvent = SIOUXHandleOneEvent(&macEvent);
  237.     //    if (!SIOUXDidEvent)
  238.         {
  239.             SetUpdateCommandStatus(false);
  240.             
  241.                 // Let Attachments process the event. Continue with normal
  242.                 // event dispatching unless suppressed by an Attachment.
  243.  
  244.             if (LAttachable::ExecuteAttachments(msg_Event, &macEvent)) {
  245.                 if (gotEvent) {
  246.                     DispatchEvent(macEvent);
  247.                 } else {
  248.                     UseIdleTime(macEvent);
  249.                 }
  250.             }
  251.         }
  252.                                             // Repeaters get time after every event
  253.         LPeriodical::DevoteTimeToRepeaters(macEvent);
  254.         
  255.                                         // Update status of menu items
  256.         if (IsOnDuty() && GetUpdateCommandStatus()) {
  257.             UpdateMenus();
  258.         }
  259.     }
  260.     else if (IsPressed(vkey_F12))
  261.         gCallWNE = true;
  262.  
  263.     if (theGame && bRunning /*&& IsPressed(vkey_F1)*/)
  264.     {
  265.         size_t    messageLen;
  266.         UInt32    interval;
  267.             
  268.         UInt32 count = TickCount();
  269.         if ( count >= gLastTickCount)
  270.         {    
  271.             TKeyState    state;
  272.             
  273.             switch(gSendRate)
  274.             {
  275.                 case 1:
  276.                     interval = 60;
  277.                 break;
  278.                 case 2:
  279.                     interval = 6;
  280.                 break;
  281.                 case 3:
  282.                     interval = 2;
  283.             };
  284.             
  285.             gLastTickCount = count + interval;
  286.     
  287.             switch(gSendSize)
  288.             {
  289.                 case 1:
  290.                     messageLen = sizeof(TKeyState);
  291.                     theMessage = (NSpMessageHeader *)&state;
  292.                 break;
  293.                 case 2:
  294.                     messageLen = 1024;
  295.                     theMessage = (NSpMessageHeader *) oneKMessage;
  296.                 break;
  297.                 case 3:
  298.                     messageLen = 10 * 1024;
  299.                     theMessage = (NSpMessageHeader *) tenKMessage;
  300.                 break;
  301.             }
  302.         
  303.             NSpClearMessageHeader(theMessage);
  304.             theMessage->what = kKeyboardState;
  305.             theMessage->to = kNSpAllPlayers;
  306.             theMessage->messageLen = messageLen;
  307.             
  308.             ((TKeyState *)theMessage)->keyMap[0] = IsPressed(0x7e) ? 1 : 0;
  309.             ((TKeyState *)theMessage)->keyMap[1] = IsPressed(0x7d) ? 1 : 0;
  310.             ((TKeyState *)theMessage)->keyMap[2] = IsPressed(0x7c) ? 1 : 0;
  311.             ((TKeyState *)theMessage)->keyMap[3] = IsPressed(0x7b) ? 1 : 0;
  312.             ((TKeyState *)theMessage)->pulseBit = gPulseBit;
  313.             gPulseBit = (gPulseBit == 1) ? 0 : 1;
  314.  
  315.             switch(gMessagePriority)
  316.             {
  317.                 case 1: 
  318.                     flags = kNSpSendFlag_Junk;
  319.                 break;
  320.                 case 2:
  321.                     flags = kNSpSendFlag_Normal;
  322.                 break;
  323.                 case 3:
  324.                     flags = kNSpSendFlag_Registered;
  325.                 break;
  326.             }
  327.             flags |= kNSpSendFlag_SelfSend;
  328.             flags |= kNSpSendFlag_FailIfPipeFull;
  329.  
  330.             if (gBlocking)
  331.                 flags |= kNSpSendFlag_Blocking;
  332.  
  333.             status = NSpMessage_Send(theGame, theMessage, flags);    
  334.             if (status != noErr)
  335.                 cout << "NSpMessage_Send returned: " << status << endl;
  336.         }    
  337.     }
  338.     
  339.     if (theGame)
  340.     {
  341.         while ((theMessage = NSpMessage_Get(theGame)) != NULL)
  342.         {
  343.             HandleGameEvent(theMessage);
  344.             NSpMessage_Release(theGame, (NSpMessageHeader *)theMessage);
  345.             if (gGameOver)
  346.             {
  347.                 status = NSpGame_Dispose(theGame, 0);
  348.                 cout << "NSpGame_Dispose returned " << status << endl;
  349.                 theGame = NULL;
  350.                 bRunning = false;
  351.                 break;
  352.             }
  353.         }
  354.     }
  355.         
  356. }
  357.  
  358.  
  359. void NSTestApp::HandleGameEvent(NSpMessageHeader *inEvent)
  360. {
  361. #if VERBOSE
  362.     cout << "Handling event:";
  363.     cout << "\twhat = " << inEvent->what << endl;
  364.     cout << "\twhen = " << inEvent->when << endl;
  365.     cout << "\tfrom = " << inEvent->from << endl;
  366.     cout << "\tto = " << inEvent->to << endl;
  367.     cout << "\tid = " << inEvent->id << endl;
  368.     cout << "\tmessageLen = " << inEvent->messageLen << endl;
  369. #endif
  370.     switch (inEvent->what)
  371.     {
  372.         case kNSpJoinApproved:
  373.         break;
  374.         case kNSpJoinDenied:
  375.         break;
  376.         case kNSpPlayerJoined:
  377.             HandlePlayerJoined((NSpPlayerJoinedMessage *)inEvent);
  378.         break;
  379.         case kNSpPlayerLeft:
  380.             HandlePlayerLeft((NSpPlayerLeftMessage *)inEvent);
  381.         break;
  382.         case kKeyboardState:
  383.             HandleKeyboardState((TKeyState *)inEvent);
  384.         break;
  385.         case kGameStart:
  386.             HandleGameStart(inEvent);
  387.         break;
  388.         case kGameEnd:
  389.             HandleGameEnd(inEvent);
  390.         break;
  391.         case kNSpGameTerminated:
  392.             HandleGameTerminated((NSpGameTerminatedMessage *) inEvent);
  393.         break;
  394.         case kTestGroups:
  395.             HandleTestGroups(inEvent);
  396.         break;
  397.         case kPropogateOptions:
  398.             HandlePropogateOptions((OptionsMessage *) inEvent);
  399.         break;
  400.         case kResyncMessage:
  401.             HandleResyncMessage((TKeyState *) inEvent);
  402.         break;
  403.         default:
  404.             cout << "Unhandled game event:" << inEvent->what << endl;
  405.         break;
  406.     }
  407. }
  408.  
  409. void NSTestApp::HandlePlayerJoined(NSpPlayerJoinedMessage *inEvent)
  410. {
  411.     PlayerListItem item;
  412.     NSpMessageHeader    theMessage;
  413.     OSStatus        status;
  414.     
  415.     cout << "In HandlePlayerJoined" << endl;
  416.  
  417.     if (inEvent->playerInfo.id == NSpPlayer_GetMyID(theGame))
  418.         return;
  419.         
  420.     if (bRunning)
  421.     {
  422.         if (bHost)
  423.         {
  424.             NSpClearMessageHeader(&theMessage);
  425.             theMessage.what = kGameStart;
  426.             theMessage.to = inEvent->playerInfo.id;
  427.             theMessage.messageLen = sizeof(NSpMessageHeader);
  428.             
  429.             status = NSpMessage_Send(theGame, &theMessage, kNSpSendFlag_Registered);
  430.             ThrowIfOSErr_(status);
  431.         }
  432.         
  433.         LWindow *window = LWindow::CreateWindow(1002, this);
  434.         ThrowIfNULL_(window);
  435.         window->SetDescriptor(inEvent->playerInfo.name);
  436.         window->Show();
  437.         item.player = inEvent->playerInfo.id;
  438.         item.window = window;
  439.         mPlayerList->InsertItemsAt(1, 0, &item);
  440.     }
  441.     
  442. }
  443.  
  444. void NSTestApp::HandlePlayerLeft(NSpPlayerLeftMessage *inEvent)
  445. {
  446.     cout << "In HandlePlayerLeft" << endl;
  447.     
  448.     ArrayIndexT    index = mPlayerList->FetchIndexOfKey(&inEvent->playerID);
  449.     PlayerListItem item;
  450.     if (mPlayerList->FetchItemAt(index, &item))
  451.         item.window->DoClose();
  452.     mPlayerList->RemoveItemsAt(1, index);
  453. }
  454.  
  455. void NSTestApp::HandleGameStart(NSpMessageHeader *inEvent)
  456. {
  457.     UInt32    i;
  458.     LWindow    *window;
  459.     PlayerListItem item;
  460.     LStr255    title;
  461.     OSStatus    err;
  462.  
  463.     NSpPlayerEnumerationPtr     thePlayers;
  464.     NSpPlayerInfoPtr    playerInfo;
  465.             
  466.     err = NSpPlayer_GetEnumeration(theGame, &thePlayers);
  467.     if (err == noErr)
  468.     {
  469.         for (i = 0; i < thePlayers->count; i++)
  470.         {
  471.             playerInfo = thePlayers->playerInfo[i];
  472.             window = LWindow::CreateWindow(1002, this);
  473.             window->SetDescriptor(playerInfo->name);
  474.             window->Show();
  475.             item.player = playerInfo->id;
  476.             item.window = window;
  477.             
  478.             mPlayerList->InsertItemsAt(1, 0, &item);
  479.             
  480.         }
  481.         
  482.         NSpPlayer_ReleaseEnumeration(theGame, thePlayers);
  483.     }
  484.     else
  485.         cout << "NSpPlayer_GetEnumeration returned " << err << endl;
  486.         
  487.     bRunning = true;
  488. }
  489.  
  490. void NSTestApp::HandleGamePause(NSpMessageHeader *inEvent)
  491. {
  492.     cout << "In HandleGamePause" << endl;
  493. }
  494.  
  495. void NSTestApp::HandleGameEnd(NSpMessageHeader *inEvent)
  496. {
  497.     cout << "In HandleGameEnd" << endl;
  498.     PlayerListItem item;
  499.     LArrayIterator     iter(*mPlayerList);
  500.     
  501.     while(iter.Next(&item))
  502.     {
  503.         item.window->DoClose();
  504.     }    
  505.     
  506.     mPlayerList->RemoveItemsAt(mPlayerList->GetCount(), LArray::index_First);
  507.     
  508.     bRunning = false;
  509. }
  510.  
  511. void NSTestApp::HandleGameTerminated(NSpGameTerminatedMessage *inMessage)
  512. {
  513.     gGameOver = true;
  514. }
  515.  
  516. void NSTestApp::HandleTestGroups(NSpMessageHeader *inEvent)
  517. {
  518.     cout << "\t!!Received a message to group " << inEvent->to << endl;
  519. }
  520.  
  521. void NSTestApp::HandleResyncMessage(TKeyState *inEvent)
  522. {
  523.     cout << "Received a resync message" <<  endl;
  524. }
  525.  
  526. void NSTestApp::HandleKeyboardState(TKeyState *inEvent)
  527. {
  528.     PlayerListItem info;
  529.     ArrayIndexT    index;
  530.     UnsignedWide    elapsedTime;
  531.     
  532.     index = mPlayerList->FetchIndexOfKey(&inEvent->h.from);
  533. #if DEBUG
  534.     if (index == LArray::index_Bad)
  535.         cout << "Got a bad player list index in HandleKeyboardState" << endl;
  536. #endif
  537.     if (mPlayerList->FetchItemAt(index, &info))
  538.     {
  539.         CPlayerWindow *theWindow = (CPlayerWindow *)info.window;
  540.         
  541.         if (theWindow)
  542.         {
  543.             theWindow->mUp = inEvent->keyMap[0];
  544.             theWindow->mDown = inEvent->keyMap[1];
  545.             theWindow->mLeft = inEvent->keyMap[2];
  546.             theWindow->mRight = inEvent->keyMap[3];
  547.             theWindow->mPulse = inEvent->pulseBit;
  548.             theWindow->mTransitTime = inEvent->h.when;
  549.             theWindow->Refresh();
  550.             theWindow->UpdatePort();
  551.         }
  552.     }
  553. }
  554.  
  555. void NSTestApp::HandlePropogateOptions(OptionsMessage *inMessage)
  556. {
  557.     gMessagePriority = inMessage->priority;
  558.     gSendRate = inMessage->rate;
  559.     gSendSize = inMessage->size;        
  560.     
  561.     LCommander::SetUpdateCommandStatus(true);    
  562.     
  563.     cout << "Received Options Propogation message from player " << inMessage->header.from << endl;
  564. }
  565.  
  566. // ---------------------------------------------------------------------------
  567. //        • ObeyCommand
  568. // ---------------------------------------------------------------------------
  569. //    Respond to commands
  570.  
  571. NSpProtocolListReference    theList;
  572.  
  573. Boolean
  574. NSTestApp::ObeyCommand(
  575.     CommandT    inCommand,
  576.     void        *ioParam)
  577. {
  578.     Boolean        cmdHandled = true;
  579.     
  580.     switch (inCommand) {
  581.         case cmd_Host:
  582.             DoHost();
  583.         break;
  584.         case cmd_Join:
  585.             DoJoin();
  586.         break;
  587.         case cmd_GetInfo:
  588.             DoGetInfo();
  589.         break;
  590.         case cmd_GetPlayers:
  591.             DoGetPlayers();
  592.         break;
  593.         case cmd_GetGroups:
  594.             DoGetGroups();
  595.         break;
  596.         case cmd_TestGroups:
  597.             DoTestGroups();
  598.         break;
  599.         case cmd_Unadvertise:
  600.             DoUnadvertise();
  601.         break;
  602.         case cmd_Start:
  603.             DoStartGame();
  604.         break;
  605.         case cmd_Stop:
  606.             DoGameEnd();
  607.         break;
  608.         case cmd_Quit:
  609.             DoKillGame();
  610.             LApplication::ObeyCommand(inCommand, ioParam);
  611.         break;
  612.         case 3001:
  613.             gMessagePriority = 1;
  614.         break;
  615.         case 3002:
  616.             gMessagePriority = 2;
  617.         break;
  618.         case 3003:
  619.             gMessagePriority = 3;
  620.         break;
  621.         case 3004:
  622.             gSendRate = 1;
  623.         break;
  624.         case 3005:
  625.             gSendRate = 2;
  626.         break;
  627.         case 3006:
  628.             gSendRate = 3;
  629.         break;
  630.         case 3007:
  631.             gSendSize = 1;
  632.         break;
  633.         case 3008:
  634.             gSendSize = 2;
  635.         break;
  636.         case 3009:
  637.             gSendSize = 3;
  638.         break;
  639.         case 3011:
  640.             DoResetOptions();
  641.         case 3010:
  642.             DoPropogateOptions();
  643.         break;
  644.         case 3012:
  645.             DoSendResyncMessage();
  646.         break;
  647.         case 3013:
  648.             gBlocking = !gBlocking;
  649.         break;
  650.         case 3014:
  651.             if (gCallWNE)
  652.                 cout << "Hit F12 to resume calling WaitNextEvent" << endl;
  653.             gCallWNE = !gCallWNE;
  654.         break;
  655.         default:
  656.             cmdHandled = LApplication::ObeyCommand(inCommand, ioParam);
  657.             break;
  658.     }
  659.     
  660.     return cmdHandled;
  661. }
  662.  
  663. // ---------------------------------------------------------------------------
  664. //        • FindCommandStatus
  665. // ---------------------------------------------------------------------------
  666. //    This function enables menu commands.
  667. //
  668.  
  669. void
  670. NSTestApp::FindCommandStatus(
  671.     CommandT    inCommand,
  672.     Boolean        &outEnabled,
  673.     Boolean        &outUsesMark,
  674.     Char16        &outMark,
  675.     Str255        outName)
  676. {
  677.  
  678.     switch (inCommand) {
  679.     
  680.         // Return menu item status according to command messages.
  681.         // Any that you don't handle will be passed to LApplication
  682.  
  683.         case cmd_Start:
  684.             if (!bRunning)
  685.                 outEnabled = true;
  686.         break;
  687.         case cmd_Stop:
  688.             if (bRunning)
  689.                 outEnabled = true;
  690.         break;
  691.         case cmd_Host:
  692.         case cmd_Join:
  693.         case cmd_GetInfo:
  694.         case cmd_Unadvertise:
  695.         case cmd_TestGroups:
  696.         case cmd_GetPlayers:
  697.         case cmd_GetGroups:
  698.         case 3010:
  699.         case 3011:
  700.         case 3012:
  701.             outEnabled = true;
  702.         break;
  703.         case 3001:
  704.             outEnabled = true;
  705.             outUsesMark = true;
  706.             if (gMessagePriority == 1)
  707.                 outMark = checkMark;
  708.             else
  709.                 outMark = noMark;
  710.         break;
  711.         case 3002:
  712.             outEnabled = true;
  713.             outUsesMark = true;
  714.             if (gMessagePriority == 2)
  715.                 outMark = checkMark;
  716.             else
  717.                 outMark = noMark;
  718.         break;
  719.         case 3003:
  720.             outEnabled = true;
  721.             outUsesMark = true;
  722.             if (gMessagePriority == 3)
  723.                 outMark = checkMark;
  724.             else
  725.                 outMark = noMark;
  726.         break;
  727.         case 3004:
  728.             outEnabled = true;
  729.             outUsesMark = true;
  730.             if (gSendRate == 1)
  731.                 outMark = checkMark;
  732.             else
  733.                 outMark = noMark;
  734.         break;
  735.         case 3005:
  736.             outEnabled = true;
  737.             outUsesMark = true;
  738.             if (gSendRate == 2)
  739.                 outMark = checkMark;
  740.             else
  741.                 outMark = noMark;
  742.         break;
  743.         case 3006:
  744.             outEnabled = true;
  745.             outUsesMark = true;
  746.             if (gSendRate == 3)
  747.                 outMark = checkMark;
  748.             else
  749.                 outMark = noMark;
  750.         break;
  751.         case 3007:
  752.             outEnabled = true;
  753.             outUsesMark = true;
  754.             if (gSendSize == 1)
  755.                 outMark = checkMark;
  756.             else
  757.                 outMark = noMark;
  758.         break;
  759.         case 3008:
  760.             outEnabled = true;
  761.             outUsesMark = true;
  762.             if (gSendSize == 2)
  763.                 outMark = checkMark;
  764.             else
  765.                 outMark = noMark;
  766.         break;
  767.         case 3009:
  768.             outEnabled = true;
  769.             outUsesMark = true;
  770.             if (gSendSize == 3)
  771.                 outMark = checkMark;
  772.             else
  773.                 outMark = noMark;
  774.         break;
  775.         case 3013:
  776.             outEnabled = true;
  777.             outUsesMark = true;
  778.             if (gBlocking)
  779.                 outMark = checkMark;
  780.             else
  781.                 outMark = noMark;
  782.         break;
  783.         case 3014:
  784.             outEnabled = true;
  785.             outUsesMark = true;
  786.             if (gCallWNE)
  787.                 outMark = checkMark;
  788.             else
  789.                 outMark = noMark;
  790.         break;
  791.         default:
  792.             LApplication::FindCommandStatus(inCommand, outEnabled,
  793.                                                 outUsesMark, outMark, outName);
  794.             break;
  795.     }
  796. }
  797.  
  798.  
  799.  
  800.  
  801.  
  802.  
  803.  
  804. void NSTestApp::DoHost(void)
  805. {
  806.  
  807.     OSStatus    err;
  808.     Boolean        result;
  809.     Str31        gameName;
  810.     Str31        password;
  811.     Str31        name;
  812.     
  813.     LString::CopyPStr("\pTest1", gameName);
  814.     LString::CopyPStr("\pbarney", password);
  815.     LString::CopyPStr("\pDarmok", name);
  816.  
  817.     NSpProtocolListReference    theList = NULL;
  818.     
  819.     Try_
  820.     {
  821. /*
  822.         NSpProtocolReference atRef = NSpProtocol_CreateAppleTalk(gameName, kNBPNameString, 0, 0);    
  823.         cout << "NSpProtocol_CreateAppleTalk returned (non-zero) " << atRef << endl;
  824.         NSpProtocolReference ipRef = NSpProtocol_CreateIP(2000, 0,0);
  825.         cout << "NSpProtocol_CreateIP returned (non-zero) " << ipRef << endl;
  826. */        
  827. //        err = NSpProtocolList_New(atRef, &theList);
  828.         err = NSpProtocolList_New(NULL, &theList);
  829.         cout << "NSpProtocolListRef_New returned (0) " << err << endl;
  830.         if (err != noErr)
  831.         {
  832. //            NSpProtocol_Dispose(atRef);
  833. //            atRef = NULL;
  834.         }
  835.         ThrowIfOSErr_(err);
  836.  
  837. /*        
  838.         err = NSpProtocolList_Append(theList, ipRef);
  839.         cout << "NSpProtocolList_Append returned (0) " << err << endl;
  840.         if (err != noErr)
  841.         {
  842.             NSpProtocol_Dispose(ipRef);
  843.             atRef = NULL;
  844.         }
  845. */        
  846.         ThrowIfOSErr_(err);
  847.         
  848.         result = NSpDoModalHostDialog(theList, gameName, name, password, NULL);
  849.         if (!result)
  850.         {
  851.             NSpProtocolList_Dispose(theList);
  852.             theList = NULL;
  853.             return;
  854.         }
  855.  
  856. //        If there is no name, the user doesn't want to play on this machine
  857.         gServerOnly = (name[0] == 0) ? true : false;
  858.         
  859.         err = NSpGame_Host(&theGame, theList, 12, gameName, password, name, 0, kNSpClientServer, 0);
  860.         cout << "NSpGame_Host returned (0) " << err << endl;
  861.         ThrowIfOSErr_(err);
  862.  
  863.         NSpProtocolList_Dispose(theList);
  864.         
  865.         cout << "Our NetSprocket player ID is " << NSpPlayer_GetMyID(theGame) << endl;
  866.         
  867.         bAdvertising = true;
  868.         bHost = true;
  869.     }
  870.     Catch_(code)
  871.     {
  872.         cout << "Exeption thrown in Host: " << code << endl;
  873.         if (theList)
  874.             NSpProtocolList_Dispose(theList);
  875.     }
  876. }
  877.  
  878.  
  879. void NSTestApp::DoJoin(void)
  880. {
  881.     OSStatus err = noErr;
  882.     NSpAddressReference theAddress = NULL;
  883.     Str31    name;
  884.     Str31    password;
  885.     LString::CopyPStr("\pJilad", name);
  886.     LString::CopyPStr("\pbarney", password);
  887.  
  888.     theAddress = NSpDoModalJoinDialog(kNBPNameString, "\pGame servers:", name, password, NULL);
  889.     cout << "DoModalJoinWithName returned an address ref of (non-zero) " << theAddress << endl;
  890.     if (theAddress == NULL)
  891.         return;
  892.  
  893.     err = NSpGame_Join(&theGame, theAddress, name, password, 0, (void*) kJoinRequestString, sizeof(kJoinRequestString),0);                
  894.     cout << "NSpGame_Join returned (0) " << err << endl;
  895.  
  896.     if (err == noErr)
  897.         cout << "Our NetSprocket player ID is " << NSpPlayer_GetMyID(theGame) << endl;
  898.  
  899.     NSpReleaseAddressReference(theAddress);
  900. }
  901.  
  902. void NSTestApp::DoGetInfo(void)
  903. {
  904.     OSStatus status;
  905.     NSpGameInfo    info;
  906.     
  907.     status = NSpGame_GetInfo(theGame, &info);
  908.     if (status != noErr)
  909.         cout << "NSpGame_GetInfo returned an error: " << status << endl;
  910.     else
  911.     {
  912.         cout << "Max Players: " << info.maxPlayers << endl;
  913.         cout << "Current Players: " << info.currentPlayers << endl;
  914.         cout << "Current Groups: " << info.currentGroups << endl;
  915.         cout << "Topology: " << info.topology << endl;
  916.         cout << "Game Name: " << p2cstr(info.name) << endl;
  917.         cout << "Game Password: " << p2cstr(info.password) << endl;
  918.     }
  919. }
  920. void NSTestApp::DoGetPlayers(void)
  921. {
  922.     OSStatus status;
  923.     NSpPlayerEnumerationPtr    players;
  924.     Str31    name;
  925.     
  926.     status = NSpPlayer_GetEnumeration(theGame, &players);
  927.     if (status == kNSpNoPlayersErr)
  928.     {
  929.         cout << "There are no players in the game." << endl;
  930.         return;
  931.     }
  932.     else
  933.         cout << "NSpPlayer_GetEnumeration returned (0) " << status << endl;
  934.     
  935.     if (status != noErr)
  936.         return;
  937.         
  938.     cout << "There are " << players->count << " players in the game:" << endl;
  939.     for (int i = 0; i < players->count; i++)
  940.     {
  941.         LString::CopyPStr(players->playerInfo[i]->name, name);
  942.         p2cstr(name);
  943.         cout << "Player " << players->playerInfo[i]->id << ":" << endl;
  944.         cout << "\tName: " << (char *)name << endl;
  945.         cout << "\tType: " << players->playerInfo[i]->type << endl;
  946.         cout << "\tGroup Count: " << players->playerInfo[i]->groupCount << endl;
  947.         
  948.         if (players->playerInfo[i]->groupCount > 0)
  949.         {
  950.             cout << "\tGroups: ";
  951.             for (int j = 0; j < players->playerInfo[i]->groupCount; j++)
  952.             {
  953.                 cout << players->playerInfo[i]->groups[j] << " ";
  954.             }
  955.         }
  956.         cout << endl;
  957.     }
  958.     
  959.     NSpPlayer_ReleaseEnumeration(theGame, players);
  960. }
  961.  
  962. void NSTestApp::DoGetGroups(void)
  963. {
  964.     OSStatus status;
  965.     NSpGroupEnumerationPtr    groups;
  966.     
  967.     status = NSpGroup_GetEnumeration(theGame, &groups);
  968.     if (status == kNSpNoGroupsErr)
  969.     {
  970.         cout << "There are no groups in the game." << endl;
  971.         return;
  972.     }
  973.     else
  974.         cout << "NSpGroup_GetEnumeration returned (0) " << status << endl;
  975.  
  976.  
  977.     cout << "There are " << groups->count << " groups in the game:" << endl;
  978.     for (int i = 0; i < groups->count; i++)
  979.     {
  980.         cout << "Group " << groups->groups[i]->id << ":" << endl;
  981.         cout << "\tPlayer Count: " << groups->groups[i]->playerCount << endl;
  982.         if (groups->groups[i]->playerCount > 0)
  983.         {
  984.             cout << "Players: ";
  985.             for (int j = 0; j < groups->groups[i]->playerCount; j++)
  986.             {
  987.                 cout << groups->groups[i]->players[j] << " ";
  988.             }
  989.             cout << endl;
  990.         }
  991.     }
  992. }
  993.  
  994. void NSTestApp::DoTestGroups(void)
  995. {
  996.     NSpGroupID theGroup;
  997.     NSpMessageHeader    theMessage;
  998.     OSStatus        err;
  999.     
  1000.     NSpClearMessageHeader(&theMessage);
  1001.     theMessage.what = kTestGroups;
  1002.     theMessage.messageLen = sizeof(NSpMessageHeader);
  1003.  
  1004.     err = NSpGroup_New(theGame, &theGroup);
  1005.     cout << "NSpGroup_New returned: " << err << endl;
  1006.     if (!err)
  1007.         cout << "\tCreated group number " << theGroup << endl;
  1008.  
  1009.     theMessage.to = theGroup;
  1010.                     
  1011.     err = NSpGroup_AddPlayer(theGame, theGroup, 1);
  1012.     cout << "NSpGroup_AddPlayer returned " << err << endl;
  1013.  
  1014.     err = NSpMessage_Send(theGame, &theMessage, kNSpSendFlag_Registered);
  1015.  
  1016.     err = NSpGroup_AddPlayer(theGame, theGroup, 2);
  1017.     cout << "NSpGroup_AddPlayer returned " << err << endl;
  1018.  
  1019.     err = NSpMessage_Send(theGame, &theMessage, kNSpSendFlag_Registered);
  1020.  
  1021.     err = NSpGroup_RemovePlayer(theGame, theGroup, 1);
  1022.     cout << "NSpGroup_RemovePlayer returned " << err << endl;
  1023.  
  1024.     err = NSpMessage_Send(theGame, &theMessage, kNSpSendFlag_Registered);
  1025.  
  1026.     err = NSpGroup_AddPlayer(theGame, theGroup, 1);
  1027.     cout << "NSpGroup_AddPlayer returned " << err << endl;
  1028.  
  1029. #if 0
  1030.     err = NSpGroup_Dispose(theGame, theGroup);
  1031.     cout << "NSpGroup_Dispose returned: " << err << endl;
  1032.     if (!err)
  1033.         cout << "\tDeleted group number " << theGroup << endl;
  1034.  
  1035.     err = NSpGroup_AddPlayer(theGame, theGroup, 2);
  1036.     cout << "NSpGroup_AddPlayer returned (should be err)" << err << endl;
  1037. #endif
  1038. }
  1039.  
  1040.  
  1041. void NSTestApp::DoUnadvertise(void)
  1042. {
  1043. }
  1044.  
  1045. void NSTestApp::DoStartGame(void)
  1046. {
  1047.     NSpMessageHeader theMessage;
  1048.     OSStatus    status;
  1049.     
  1050.     NSpClearMessageHeader(&theMessage);
  1051.     theMessage.what = kGameStart;
  1052.     theMessage.to = kNSpAllPlayers;
  1053.     theMessage.messageLen = sizeof(NSpMessageHeader);
  1054.     
  1055.     status = NSpMessage_Send(theGame, &theMessage, kNSpSendFlag_Registered | kNSpSendFlag_SelfSend);
  1056.     cout << "NSpMessage_Send returned (0) :" << status << endl;
  1057. }
  1058.             
  1059. void NSTestApp::DoGameEnd(void)
  1060. {
  1061.     NSpMessageHeader    theMessage;
  1062.     OSStatus            status;
  1063.     
  1064.     if (theGame && bRunning)
  1065.     {
  1066.         NSpClearMessageHeader(&theMessage);
  1067.         theMessage.what = kGameEnd;
  1068.         theMessage.to = kNSpAllPlayers;
  1069.         theMessage.messageLen = sizeof(NSpMessageHeader);
  1070.         
  1071.         status = NSpMessage_Send(theGame, &theMessage, kNSpSendFlag_Registered | kNSpSendFlag_SelfSend);
  1072.         cout << "NSpMessage_Send returned (0) :" << status << endl;
  1073.     }
  1074. }
  1075.  
  1076. void NSTestApp::DoKillGame(void)
  1077. {
  1078.     OSStatus    status;
  1079.     
  1080.     if (!theGame)
  1081.         return;
  1082.     if (bHost)
  1083.         DoGameEnd();
  1084.         
  1085.     status = NSpGame_Dispose(theGame, kNSpGameFlag_ForceTerminateGame);
  1086.     cout << "NSpGame_Dispose returned (0) :" << status << endl;
  1087.     theGame = NULL;
  1088.     
  1089.     gGameOver = true;
  1090. }
  1091.  
  1092. void NSTestApp::DoResetOptions(void)
  1093. {
  1094.     gMessagePriority = 1;
  1095.     gSendRate = 1;
  1096.     gSendSize = 1;
  1097. }
  1098.  
  1099. void NSTestApp::DoPropogateOptions(void)
  1100. {
  1101.     OptionsMessage    theMessage;
  1102.     OSStatus            status;
  1103.     
  1104.     if (theGame)
  1105.     {
  1106.         NSpClearMessageHeader(&theMessage.header);
  1107.         theMessage.header.what = kPropogateOptions;
  1108.         theMessage.header.to = kNSpAllPlayers;
  1109.         theMessage.header.messageLen = sizeof(OptionsMessage);
  1110.         theMessage.priority = gMessagePriority;
  1111.         theMessage.rate = gSendRate;
  1112.         theMessage.size = gSendSize;
  1113.         
  1114.         status = NSpMessage_Send(theGame, &theMessage.header, kNSpSendFlag_Registered);
  1115.     }
  1116. }
  1117.  
  1118. void NSTestApp::DoSendResyncMessage()
  1119. {
  1120.     NSpMessageHeader *theMessage;
  1121.     OSStatus    status;
  1122.     theMessage = (NSpMessageHeader *) tenKMessage;
  1123.         
  1124.     NSpClearMessageHeader(theMessage);
  1125.     theMessage->what = kResyncMessage;
  1126.     theMessage->to = kNSpAllPlayers;
  1127.     theMessage->messageLen = 10 * 1024;
  1128.     
  1129.     ((TKeyState *)theMessage)->keyMap[0] = IsPressed(0x7e) ? 1 : 0;
  1130.     ((TKeyState *)theMessage)->keyMap[1] = IsPressed(0x7d) ? 1 : 0;
  1131.     ((TKeyState *)theMessage)->keyMap[2] = IsPressed(0x7c) ? 1 : 0;
  1132.     ((TKeyState *)theMessage)->keyMap[3] = IsPressed(0x7b) ? 1 : 0;
  1133.     ((TKeyState *)theMessage)->pulseBit = gPulseBit;
  1134.     gPulseBit = (gPulseBit == 1) ? 0 : 1;
  1135.  
  1136.     status = NSpMessage_Send(theGame, theMessage, kNSpSendFlag_SelfSend | kNSpSendFlag_Registered | kNSpSendFlag_FailIfPipeFull);    
  1137.     if (status != noErr)
  1138.         cout << "NSpMessage_Send returned: " << status << endl;
  1139. }
  1140. Int32
  1141. CPlayerListComparator::Compare(
  1142.     const void*        inItemOne,
  1143.     const void*        inItemTwo,
  1144.     Uint32            /* inSizeOne */,
  1145.     Uint32            /* inSizeTwo */) const
  1146. {
  1147.     return ( (((PlayerListItem *)inItemOne)->player) - (((PlayerListItem *)inItemTwo)->player) );
  1148. }
  1149.  
  1150.  
  1151. Boolean
  1152. CPlayerListComparator::IsEqualTo(
  1153.     const void*        inItemOne,
  1154.     const void*        inItemTwo,
  1155.     Uint32            /* inSizeOne */,
  1156.     Uint32            /* inSizeTwo */) const
  1157. {
  1158.     return ( (((PlayerListItem *)inItemOne)->player) == (((PlayerListItem *)inItemTwo)->player) );
  1159. }
  1160.  
  1161.  
  1162. Int32
  1163. CPlayerListComparator::CompareToKey(
  1164.     const void*         inItem ,
  1165.     Uint32            /* inSize */,
  1166.     const void*         inKey ) const
  1167. {
  1168.     return ( (((PlayerListItem *)inItem)->player) - (*(NSpPlayerID *)inKey) );
  1169. }
  1170.                                 
  1171.  
  1172. Boolean
  1173. CPlayerListComparator::IsEqualToKey(
  1174.     const void*        inItem,
  1175.     Uint32            inSize,
  1176.     const void*        inKey) const
  1177. {
  1178.     return ( (((PlayerListItem *)inItem)->player) == (*(NSpPlayerID *)inKey) );
  1179. }
  1180.